<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">






  
  
  <link rel="stylesheet" media="all" href="/lib/Han/dist/han.min.css?v=3.3">




<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.png?v=5.1.4">


  <link rel="mask-icon" href="/images/favicon.png?v=5.1.4" color="#222">





  <meta name="keywords" content="C++," />





  <link rel="alternate" href="/atom.xml" title="平步青云win" type="application/atom+xml" />






<meta name="description" content="C++11中的一些新特性。">
<meta name="keywords" content="C++">
<meta property="og:type" content="article">
<meta property="og:title" content="C++2.0(11)新特性">
<meta property="og:url" content="https://zxpgo.github.io/2019/08/03/C++2.0新特性/index.html">
<meta property="og:site_name" content="平步青云win">
<meta property="og:description" content="C++11中的一些新特性。">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805162438.png">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805163657.png">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805163412.png">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805194857.png">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805200019.png">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190806130246.png">
<meta property="og:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190806134854.png">
<meta property="og:updated_time" content="2020-04-25T09:34:45.040Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="C++2.0(11)新特性">
<meta name="twitter:description" content="C++11中的一些新特性。">
<meta name="twitter:image" content="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805162438.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"right","display":"post","offset":10,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: 'PAO8LM7QB1',
      apiKey: '',
      indexName: 'Blog',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://zxpgo.github.io/2019/08/03/C++2.0新特性/"/>





  <title>C++2.0(11)新特性 | 平步青云win</title>
  





  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?7a4517a3ce6d7c50203655d056f01ac3";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-right page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">平步青云win</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <h1 class="site-subtitle" itemprop="description"></h1>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-随笔">
          <a href="/sui" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br />
            
            随笔
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
			
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://zxpgo.github.io/2019/08/03/C++2.0新特性/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="zxp">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="平步青云win">
    </span>

    
      <header class="post-header">

        
        
          <h2 class="post-title" itemprop="name headline">C++2.0(11)新特性</h2>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2019-08-03T22:28:50+08:00">
                2019-08-03
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/C/" itemprop="url" rel="index">
                    <span itemprop="name">C++</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          
             <span id="/2019/08/03/C++2.0新特性/" class="leancloud_visitors" data-flag-title="C++2.0(11)新特性">
               <span class="post-meta-divider">|</span>
               <span class="post-meta-item-icon">
                 <i class="fa fa-eye"></i>
               </span>
               
                 <span class="post-meta-item-text">阅读次数&#58;</span>
               
                 <span class="leancloud-visitors-count"></span>
             </span>
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body han-init-context" itemprop="articleBody">

      
      

      
        <p>C++11中的一些新特性。<a id="more"></a></p>
<h2 id="C-演化"><a href="#C-演化" class="headerlink" title="C++演化"></a>C++演化</h2><p>C++ 98  (1.0)</p>
<p>C++ 03 （TR1,Technical Report 1）</p>
<p>C++11 （2.0）</p>
<p>C++14</p>
<h2 id="Header-files"><a href="#Header-files" class="headerlink" title="Header files"></a>Header files</h2><p>C++2.0特性包括语言和标准库两部分，后者以header files形式呈现。</p>
<ul>
<li>C++标准库的header files不带副档名(.h)，例如<code>#include&lt;vector&gt;</code></li>
<li>新版本C header files不带.h，例如<code>#include&lt;csdtio&gt;</code></li>
<li>新版本C header files带有.h的仍可用，例如<code>#include&lt;stdio.h&gt;</code></li>
</ul>
<p>许多TR1的特性之前仅仅存在std::tr1中，但是现在已经迁移到std命名空间中。</p>
<h2 id="语言"><a href="#语言" class="headerlink" title="语言"></a>语言</h2><h3 id="Variadic-Templates-参数可变模板"><a href="#Variadic-Templates-参数可变模板" class="headerlink" title="Variadic Templates(参数可变模板)"></a>Variadic Templates(参数可变模板)</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">()</span></span>&#123;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span>... Types&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">const</span> T&amp; firstArg, <span class="keyword">const</span> Types&amp;... args)</span></span>&#123;</span><br><span class="line">	<span class="built_in">cout</span> &lt;&lt; firstArg &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">	print(args...);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><p>参数可变模板可以实现递归。</p>
</li>
<li><p>在使用参数可变模板时，一定需要一个处理最后一个问题的函数(这里是参数为空时)。</p>
</li>
</ul>
<p>…就是一个所谓的pack（包）</p>
<ul>
<li><p>模板参数包：typename…</p>
</li>
<li><p>函数参数类型包: Types &amp;…</p>
</li>
<li><p>函数参数包: args…</p>
</li>
</ul>
<p>具体的例子有：</p>
<ul>
<li>hash function实现</li>
<li>tuple实现</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span>... Values&gt; <span class="class"><span class="keyword">class</span> <span class="title">tuple</span>;</span></span><br><span class="line"><span class="keyword">template</span>&lt;&gt; <span class="class"><span class="keyword">class</span> <span class="title">tuple</span>&lt;&gt;&#123;</span>&#125;;</span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> Head, <span class="keyword">typename</span>... Tail&gt;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">tuple</span>&lt;Head, Tail...&gt;:</span><span class="keyword">private</span> tuple&lt;Tail...&gt;&#123;</span><br><span class="line">	<span class="keyword">typedef</span> tuple&lt;Tail...&gt; inherited;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	tuple()&#123;&#125;</span><br><span class="line">	tuple(Head v, Tail... vtail)</span><br><span class="line">	: m_head(v), inherited(vtail...&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="keyword">typename</span> Head::type head() &#123;</span><br><span class="line">		<span class="keyword">return</span> m_head;</span><br><span class="line">	&#125;</span><br><span class="line">	inherited &amp; tial()&#123;</span><br><span class="line">		<span class="keyword">return</span> *<span class="keyword">this</span>;</span><br><span class="line">	&#125;</span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line">	Head m_head;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tupel&lt;<span class="keyword">int</span>, <span class="keyword">float</span>, <span class="built_in">string</span>&gt; t(<span class="number">41</span>, <span class="number">6.3</span>, <span class="string">"nico"</span>);</span><br></pre></td></tr></table></figure>
<h3 id="模板表达式中的空格"><a href="#模板表达式中的空格" class="headerlink" title="模板表达式中的空格"></a>模板表达式中的空格</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">list</span>&lt;<span class="keyword">int</span>&gt; &gt;; <span class="comment">//OK in each C++ version</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">list</span>&lt;<span class="keyword">int</span>&gt;&gt;; <span class="comment">//OK since C++11</span></span><br></pre></td></tr></table></figure>
<h3 id="nullptr和std-nullptr-t"><a href="#nullptr和std-nullptr-t" class="headerlink" title="nullptr和std::nullptr_t"></a><code>nullptr</code>和<code>std::nullptr_t</code></h3><p>C++可以使用<code>nullptr</code>来代替0或者NULL。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(<span class="keyword">int</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(<span class="keyword">void</span>*)</span></span>;</span><br><span class="line">f(<span class="number">0</span>);  <span class="comment">// calls  f(int)</span></span><br><span class="line">f(<span class="literal">NULL</span>); <span class="comment">// calls f(int) if NULL is 0，if NULL is other value, can not calls which function</span></span><br><span class="line">f(<span class="literal">nullptr</span>); <span class="comment">// calls f(void *)，即使nulptr是0，calls f(void *)</span></span><br></pre></td></tr></table></figure>
<h3 id="auto"><a href="#auto" class="headerlink" title="auto"></a>auto</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> i = <span class="number">42</span>;</span><br><span class="line"><span class="function"><span class="keyword">double</span> <span class="title">f</span><span class="params">()</span></span>;</span><br><span class="line"><span class="keyword">auto</span> d = f();</span><br></pre></td></tr></table></figure>
<p><strong>注意：</strong>auto 变量是局部函数里面的变量，在函数结束时，会自动释放。这是之前的意思，在这里，auto是自动推断变量的类型。</p>
<p>auto特别使用在变量的类型特别长或复杂的情况。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> pos = v.begin();</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;::iterator pos = v.begin();</span><br><span class="line"></span><br><span class="line"><span class="comment">//lambda表达式</span></span><br><span class="line"><span class="keyword">auto</span> l = [](<span class="keyword">int</span> x)-&gt;<span class="keyword">bool</span>&#123;</span><br><span class="line">  ...	   </span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//l是一个对象</span></span><br></pre></td></tr></table></figure>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">list</span>&lt;<span class="built_in">string</span>&gt; c;</span><br><span class="line"><span class="built_in">list</span>&lt;<span class="built_in">string</span>&gt;::iterator ite;</span><br><span class="line">ite = find(c.begin(), c.end(), target);</span><br><span class="line"></span><br><span class="line"><span class="built_in">list</span>&lt;<span class="built_in">string</span>&gt; c;</span><br><span class="line"><span class="keyword">auto</span> = find(c.begin(), c.end(), target);</span><br></pre></td></tr></table></figure>
<h3 id="Uniform-Initialization-一致性初始化"><a href="#Uniform-Initialization-一致性初始化" class="headerlink" title="Uniform Initialization(一致性初始化)"></a>Uniform Initialization(一致性初始化)</h3><p>所有变量的初始化都是可以使用大括号。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> values[] &#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;;</span><br><span class="line">vecotr&lt;<span class="keyword">int</span>&gt; v &#123;<span class="number">2</span>，<span class="number">3</span>，<span class="number">4</span>，<span class="number">5</span>，<span class="number">6</span>&#125;;</span><br><span class="line"><span class="keyword">complex</span>&lt;<span class="keyword">double</span>&gt; c&#123;<span class="number">4.0</span>,<span class="number">3.0</span>&#125;;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; cities&#123;<span class="string">"Berlin"</span>, <span class="string">"New York"</span>&#125;;</span><br></pre></td></tr></table></figure>
<p>其实是利用一个事实，编译器看到<code>{t1,t2,...,tn}</code>便做出一个<code>initializer_list&lt;T&gt;</code>，它关联到一个<code>array&lt;T,n&gt;</code>。调用函数时该array内的元素可被编译器分解逐一传给函数。但若函数参数是个<code>initializer_list&lt;T&gt;</code>类型时，调用者却不能给予数个T参数然后以为它们会被自动转为一个<code>initializer_list&lt;T&gt;</code>。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; cities&#123;<span class="string">"Berlin"</span>, <span class="string">"New York"</span>&#125;;</span><br></pre></td></tr></table></figure>
<p>背后有一个<code>array&lt;strng,6&gt;</code>调用<code>vector&lt;string&gt; ctors</code>时编译器找到一个<code>vector&lt;stirng&gt; ctor</code>接收<code>initializer_list&lt;string&gt;</code>。所有容器皆有如此ctor(构造函数)。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">complex</span>&lt;<span class="keyword">double</span>&gt; c&#123;<span class="number">4.0</span>,<span class="number">3.0</span>&#125;;</span><br></pre></td></tr></table></figure>
<p>这个形成一个<code>initializer_list&lt;double&gt;</code>背后有个<code>array&lt;double,2&gt;</code>。调用<code>complex&lt;double&gt; ctor</code>时该array内的2个元素被分解传给ctor，<code>complex&lt;double&gt;</code>并无任何ctor接收<code>initializer_list</code>。</p>
<h3 id="Initializer-lists"><a href="#Initializer-lists" class="headerlink" title="Initializer lists"></a>Initializer lists</h3><p>{}可以用来设置初值。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> i; <span class="comment">//没有初值</span></span><br><span class="line"><span class="keyword">int</span> j &#123;&#125;; <span class="comment">//初值为0</span></span><br><span class="line"><span class="keyword">int</span> * p;<span class="comment">//没有初值</span></span><br><span class="line"><span class="keyword">int</span> * q&#123;&#125;;<span class="comment">//初值为nullptr</span></span><br></pre></td></tr></table></figure>
<p>不允许窄化：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">x1</span><span class="params">(<span class="number">5.3</span>)</span></span>; <span class="comment">//5</span></span><br><span class="line"><span class="keyword">int</span> x2 = <span class="number">5.3</span>; <span class="comment">//5</span></span><br><span class="line"><span class="keyword">int</span> x3 &#123;<span class="number">5.3</span>&#125;; <span class="comment">//Error or Warming</span></span><br><span class="line"><span class="keyword">int</span> x4 = &#123;<span class="number">5.3</span>&#125; <span class="comment">// Error or Warming</span></span><br></pre></td></tr></table></figure>
<h3 id="initializer-list-lt-gt"><a href="#initializer-list-lt-gt" class="headerlink" title="initializer_list&lt;&gt;"></a>initializer_list&lt;&gt;</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="built_in">std</span>::<span class="built_in">initializer_list</span>&lt;<span class="keyword">int</span>&gt; vals)</span></span>&#123;</span><br><span class="line">	<span class="keyword">for</span> (<span class="keyword">auto</span> p = val.begin(); p != val.end(); ++p)&#123;</span><br><span class="line">        <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; * p &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">P</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	P(<span class="keyword">int</span> a, <span class="keyword">int</span> b) &#123;  <span class="comment">//#1</span></span><br><span class="line">		<span class="built_in">cout</span> &lt;&lt; <span class="string">"P(int ,int), a = "</span> &lt;&lt; a &lt;&lt; <span class="string">", b = "</span> &lt;&lt; b &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	P(<span class="built_in">initializer_list</span>&lt;<span class="keyword">int</span>&gt; intlist) &#123; <span class="comment">//#2</span></span><br><span class="line">		<span class="built_in">cout</span> &lt;&lt; <span class="string">"P(initializer_list&lt;int&gt;, value= "</span>;</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">auto</span> i : intlist) &#123;</span><br><span class="line">			<span class="built_in">cout</span> &lt;&lt; i &lt;&lt; <span class="string">' '</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="built_in">cout</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function">P <span class="title">p</span><span class="params">(<span class="number">77</span>, <span class="number">5</span>)</span></span>; <span class="comment">//calls #1</span></span><br><span class="line">P q&#123; <span class="number">77</span>,<span class="number">5</span> &#125;; <span class="comment">//calls #2</span></span><br><span class="line">P r&#123; <span class="number">77</span>, <span class="number">3</span>, <span class="number">42</span> &#125;; <span class="comment">// calls #2</span></span><br><span class="line">P s = &#123; <span class="number">77</span>,<span class="number">5</span> &#125;; <span class="comment">// calls #2</span></span><br></pre></td></tr></table></figure>
<p>如果没有版本#2，<code>P q{77,5};</code>会被拆分，调用版本#1。但是<code>P r{ 77, 3, 42 };</code>则会报错。<code>P s = { 77,5 };</code>同样会被拆分，调用版本#1。</p>
<p><code>initialzier_list</code>类的源码：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="class"><span class="keyword">class</span> _<span class="title">E</span>&gt; </span></span><br><span class="line"><span class="class"><span class="title">class</span> <span class="title">initializer_list</span></span></span><br><span class="line"><span class="class">    &#123;</span></span><br><span class="line">    <span class="keyword">public</span>:</span><br><span class="line">      <span class="keyword">typedef</span> _E 		value_type;</span><br><span class="line">      <span class="keyword">typedef</span> <span class="keyword">const</span> _E&amp; 	reference;</span><br><span class="line">      <span class="keyword">typedef</span> <span class="keyword">const</span> _E&amp; 	const_reference;</span><br><span class="line">      <span class="keyword">typedef</span> <span class="keyword">size_t</span> 		size_type;</span><br><span class="line">      <span class="keyword">typedef</span> <span class="keyword">const</span> _E* 	iterator;</span><br><span class="line">      <span class="keyword">typedef</span> <span class="keyword">const</span> _E* 	const_iterator;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span>:</span><br><span class="line">      iterator			_M_array;</span><br><span class="line">      size_type			_M_len;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// The compiler can call a private constructor.编译器可以调用一个私有构造函数</span></span><br><span class="line">      <span class="function"><span class="keyword">constexpr</span> <span class="title">initializer_list</span><span class="params">(const_iterator __a, size_type __l)</span></span></span><br><span class="line">      : _M_array(__a), _M_len(__l) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span>:</span><br><span class="line">      <span class="function"><span class="keyword">constexpr</span> <span class="title">initializer_list</span><span class="params">()</span> <span class="keyword">noexcept</span></span></span><br><span class="line">      : _M_array(0), _M_len(0) &#123; &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Number of elements.</span></span><br><span class="line">      <span class="keyword">constexpr</span> size_type</span><br><span class="line">      size() <span class="keyword">const</span> <span class="keyword">noexcept</span> &#123; <span class="keyword">return</span> _M_len; &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// First element.</span></span><br><span class="line">      <span class="keyword">constexpr</span> const_iterator</span><br><span class="line">      begin() <span class="keyword">const</span> <span class="keyword">noexcept</span> &#123; <span class="keyword">return</span> _M_array; &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// One past the last element.</span></span><br><span class="line">      <span class="keyword">constexpr</span> const_iterator</span><br><span class="line">      end() <span class="keyword">const</span> <span class="keyword">noexcept</span> &#123; <span class="keyword">return</span> begin() + size(); &#125;</span><br><span class="line">    &#125;;</span><br></pre></td></tr></table></figure>
<p><code>initializer_list</code>对象背后有一个array支持。</p>
<p>各种容器和算法都是用了`initializer_list&lt;&gt;。</p>
<p>比如，下面为<code>stl_vector.h</code>中的代码：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>(<span class="built_in">initializer_list</span>&lt;value_type&gt; __l,</span><br><span class="line">	     <span class="keyword">const</span> allocator_type&amp; __a = allocator_type())</span><br><span class="line">      : _Base(__a)</span><br><span class="line">      &#123;</span><br><span class="line">		_M_range_initialize(__l.begin(), __l.end(), random_access_iterator_tag());</span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure>
<p>max，min之前只能放入两个元素：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">max(&#123;<span class="number">12</span>,<span class="number">34</span>,<span class="number">11</span>,<span class="number">55</span>&#125;);</span><br><span class="line">min(&#123;<span class="built_in">string</span>(<span class="string">"Ace"</span>), String(<span class="string">"Stacy"</span>), String <span class="string">"Sabrina"</span>&#125;);</span><br></pre></td></tr></table></figure>
<h3 id="explicit"><a href="#explicit" class="headerlink" title="explicit"></a>explicit</h3><p>针对具有一个以上的实参的<strong>构造函数</strong>。</p>
<p>而之前的版本explicit，针对一个实参的构造函数（c++11之前）。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Complex</span>&#123;</span></span><br><span class="line">    <span class="keyword">int</span> real, imag;</span><br><span class="line">    Complex(<span class="keyword">int</span> re, <span class="keyword">int</span> im = <span class="number">0</span>) : real(re), imag(im)&#123;&#125; <span class="comment">//一个实参，因为另一个指定了默认值</span></span><br><span class="line">    Complex <span class="keyword">operator</span>+(<span class="keyword">const</span> Complex &amp; x)&#123;</span><br><span class="line">        <span class="keyword">return</span> Complex((real + x.real), (imag+x.imag));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function">Complex <span class="title">c1</span><span class="params">(<span class="number">12</span>,<span class="number">5</span>)</span></span>;</span><br><span class="line">Complex c2 = c1 + <span class="number">5</span>; <span class="comment">//5会调用第一个构造函数，隐式转换</span></span><br></pre></td></tr></table></figure>
<p>如果不想使用这种隐式转换，只有明确调用构造函数才做转换。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Complex</span>&#123;</span></span><br><span class="line">    <span class="keyword">int</span> real, imag;</span><br><span class="line">    explicit Complex(int re, int im = 0) : real(re), imag(im)&#123;&#125;</span><br><span class="line">    Complex <span class="keyword">operator</span>+(<span class="keyword">const</span> Complex &amp; x)&#123;</span><br><span class="line">        <span class="keyword">return</span> Complex((real + x.real), (imag+x.imag));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function">Complex <span class="title">c1</span><span class="params">(<span class="number">12</span>,<span class="number">5</span>)</span></span>;</span><br><span class="line">Complex c2 = c1 + <span class="number">5</span>; <span class="comment">//Error,无法进行隐式转换</span></span><br></pre></td></tr></table></figure>
<p>而对于C++11(2.0)，explicit可以用于一个以上实参的构造函数。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">P</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	P(<span class="keyword">int</span> a, <span class="keyword">int</span> b) &#123;  <span class="comment">//#1</span></span><br><span class="line">		<span class="built_in">cout</span> &lt;&lt; <span class="string">"P(int ,int) \n"</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	P(<span class="built_in">initializer_list</span>&lt;<span class="keyword">int</span>&gt; intlist) &#123; <span class="comment">//#2</span></span><br><span class="line">		<span class="built_in">cout</span> &lt;&lt; <span class="string">"P(initializer_list&lt;int&gt;\n"</span>;</span><br><span class="line">	&#125;</span><br><span class="line">    <span class="function"><span class="keyword">explicit</span> <span class="title">P</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b, <span class="keyword">int</span> c)</span></span>&#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"explicit P(int a, int b, int c)\n"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="基于范围的for"><a href="#基于范围的for" class="headerlink" title="基于范围的for"></a>基于范围的for</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (decl : coll&#123;</span><br><span class="line">    statement</span><br><span class="line">&#125;</span><br><span class="line">     </span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i: &#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>&#125;)&#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; i &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">double</span>&gt; vec;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">auto</span> elem : vec)&#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; elem &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">auto</span> &amp; elem : vec)&#123;<span class="comment">//引用</span></span><br><span class="line">    elem * = <span class="number">3</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意关联式容器是不可以修改的。</p>
<p>基于范围的for循环的实现：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (decl : coll)&#123;</span><br><span class="line">    statement</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//这是编译器所做的事，将上面的代码转换成下面的代码</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">auto</span> _pos = coll.begin(), _end=coll.end(); _pos!= _end(); ++_pos)&#123;</span><br><span class="line">    decl =  *_pos;</span><br><span class="line">    statement;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//另一个版本</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">auto</span> _pos=begin(coll), _end=end(coll); _pos!= _end(); ++_pos)&#123;</span><br><span class="line">    <span class="comment">// begin()和end()是带个全局函数</span></span><br><span class="line">    decl =  *_pos;</span><br><span class="line">    statement;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>for中类型转换：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">C</span>&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	<span class="function"><span class="keyword">explicit</span> <span class="title">C</span><span class="params">(<span class="keyword">const</span> <span class="built_in">string</span> &amp; s)</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; vs;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> C &amp; elem : vs)&#123; <span class="comment">//Error，vs是字符串，无法转化成C</span></span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; elem &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="default和-delete"><a href="#default和-delete" class="headerlink" title="=default和=delete"></a>=default和=delete</h3><p>如果你自行定义了一个构造函数，那么编译器就不会再给你一个默认的构造函数。</p>
<p>如果你强制加上=default，就可以重新获得并使用模式构造函数。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Zoo</span>&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    Zoo(<span class="keyword">int</span> i1, <span class="keyword">int</span> i2): d1(i1), d2(i2)&#123;&#125;</span><br><span class="line">    Zoo(<span class="keyword">const</span> Zoo&amp;) = <span class="keyword">delete</span>;</span><br><span class="line">    Zoo(Zoo &amp;&amp;) = <span class="keyword">default</span>;</span><br><span class="line">    Zoo &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> Zoo &amp;) = <span class="keyword">default</span>;</span><br><span class="line">    Zoo &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> Zoo &amp;&amp; = <span class="keyword">delete</span>;</span><br><span class="line">    <span class="keyword">virtual</span> ~Zoo()&#123;&#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">	<span class="keyword">int</span>  d1, d2;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><code>=default</code>表示使用编译器默认给定的，即使我们在代码中重写了。</p>
<p><code>=delete</code>表示不需要编译器默认给定的。</p>
<p>构造函数、析构函数、拷贝构造函数、移动构造函数、拷贝赋值函数、移动赋值函数编译器都会给一个默认的空函数。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> &#123;</span></span><br><span class="line">	<span class="keyword">public</span>:</span><br><span class="line">		Foo(<span class="keyword">int</span> i) : _i(i)&#123;&#125;</span><br><span class="line">		Foo() = <span class="keyword">default</span>;</span><br><span class="line"></span><br><span class="line">		Foo(<span class="keyword">const</span> Foo &amp;  x) : _i(x._i)&#123;&#125;</span><br><span class="line">		<span class="comment">//!Foo(const Foo &amp;  x) = delete; //Error</span></span><br><span class="line">		<span class="comment">//!Foo(const Foo &amp;  x) = default; //Error</span></span><br><span class="line"></span><br><span class="line">		Foo &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> Foo &amp; x)&#123; _i = x._i; <span class="keyword">return</span> (*<span class="keyword">this</span>); &#125;</span><br><span class="line">		<span class="comment">//!Foo &amp; operator=(const Foo &amp; x) = default; //Error</span></span><br><span class="line">		<span class="comment">//!Foo &amp; operator=(const Foo &amp; x) = delete;  //Error</span></span><br><span class="line">		<span class="comment">//!void func1() = default; //Error</span></span><br><span class="line">		<span class="function"><span class="keyword">void</span> <span class="title">func2</span><span class="params">()</span> </span>= <span class="keyword">delete</span>;</span><br><span class="line">		</span><br><span class="line">		~Foo() = <span class="keyword">default</span>;</span><br><span class="line">		<span class="comment">//!~Foo() = delete; //Error</span></span><br><span class="line">	<span class="keyword">private</span>:</span><br><span class="line">		<span class="keyword">int</span> _i;</span><br><span class="line">	&#125;;</span><br></pre></td></tr></table></figure>
<p>一个空类，编译器会给出一些默认的函数：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Empty</span>&#123;</span>&#125;;</span><br><span class="line"><span class="comment">//定义一个空类时，编译器会默认给出如下函数</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Empty</span>&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    Empty()&#123;&#125;</span><br><span class="line">    Empyt(<span class="keyword">const</span> Empty &amp; rhs)&#123;&#125;</span><br><span class="line">    ~Empty()&#123;&#125;</span><br><span class="line">    </span><br><span class="line">    Empty &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> Empty &amp; rhs)&#123;&#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>这些默认的函数都是public并且是inline。</p>
<p>禁止复制的类：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">NoCopy</span>&#123;</span></span><br><span class="line">	NoCopy() = <span class="keyword">default</span>;</span><br><span class="line">    NoCopy(<span class="keyword">const</span> NoCopy &amp; ) = <span class="keyword">delete</span>;</span><br><span class="line">    NoCopy &amp; <span class="keyword">operator</span> =(<span class="keyword">const</span> NoCopy&amp;) = <span class="keyword">delete</span>;</span><br><span class="line">    ~NoCopy() = <span class="keyword">default</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>一般的类无法复制，但是友元函数或者成员函数可以进行复制：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PrivateCopy</span>&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    NoCopy(<span class="keyword">const</span> NoCopy &amp; );</span><br><span class="line">    NoCopy &amp; <span class="keyword">operator</span> =(<span class="keyword">const</span> NoCopy&amp;);	</span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>boost是C++ 的一个准标准，其中的成员都是一些有影响力的人，尤其在C++社圈中，有一些很前沿的想法，做出来，经过大会讨论才会放入标准库中。boost是一个C++社群。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> boost&#123;</span><br><span class="line">    <span class="keyword">namespace</span> noncopyable_&#123;</span><br><span class="line">        <span class="class"><span class="keyword">class</span> <span class="title">noncopyable</span>&#123;</span></span><br><span class="line">            <span class="keyword">protected</span>:</span><br><span class="line">            	nonocopyable()&#123;&#125;</span><br><span class="line">            	~noncopyable()&#123;&#125;</span><br><span class="line">            <span class="keyword">private</span>:</span><br><span class="line">            	noncopyable(<span class="keyword">const</span> noncopyable &amp;);</span><br><span class="line">            	<span class="keyword">const</span> noncopyable &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> noncopyable &amp;);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">typedef</span> noncopyable_::noncopyable noncopyable;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> :</span> <span class="keyword">public</span> noncopyable&#123; <span class="comment">//Foo只有成员函数和友元函数可以拷贝</span></span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="Alias-Template-别名模板，template-typedef"><a href="#Alias-Template-别名模板，template-typedef" class="headerlink" title="Alias Template(别名模板，template typedef)"></a>Alias Template(别名模板，template typedef)</h3><p>Alias template只能声明在函数外部。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</span><br><span class="line"><span class="keyword">using</span> Vec = <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;T, MyAlloc&lt;T&gt;&gt;; <span class="comment">//vec模板的别名</span></span><br><span class="line"></span><br><span class="line">Vec&lt;<span class="keyword">int</span>&gt; coll;</span><br><span class="line"><span class="comment">//等同于</span></span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>, Myalloc&lt;<span class="keyword">int</span>&gt;&gt; coll;</span><br><span class="line"></span><br><span class="line"><span class="comment">//使用define</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Vec<span class="meta-string">&lt;T&gt; template&lt;typename T&gt; std::vector&lt;T, MyAlloc&lt;T&gt;&gt;;</span></span></span><br><span class="line"><span class="comment">//于是</span></span><br><span class="line">Vec&lt;<span class="keyword">int</span>&gt; coll;</span><br><span class="line">tempalte&lt;<span class="keyword">typename</span> <span class="keyword">int</span>&gt; <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>, MyAlloc&lt;<span class="keyword">int</span>&gt;&gt;; <span class="comment">//这不是我们想要的</span></span><br></pre></td></tr></table></figure>
<h3 id="template-template-parameter-模板模板参数"><a href="#template-template-parameter-模板模板参数" class="headerlink" title="template template parameter(模板模板参数)"></a>template template parameter(模板模板参数)</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">template</span>&lt;<span class="class"><span class="keyword">class</span> <span class="title">T</span>&gt; <span class="title">class</span> <span class="title">Container</span>&gt; //<span class="title">template</span>&lt;class T&gt; <span class="title">class</span> <span class="title">Container</span>这是一个模板，并该模板是前一个模板的参数</span></span><br><span class="line"><span class="class"><span class="title">class</span> <span class="title">XCIs</span>&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">	Container&lt;T&gt; c;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	XCIs()&#123;</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">long</span> i = <span class="number">0</span>; i &lt; size; ++i)</span><br><span class="line">			c.insert(c.end(), T()); <span class="comment">//T()是伪码</span></span><br><span class="line">		output_static_data(T());</span><br><span class="line">		Container&lt;T&gt; c1(c);</span><br><span class="line">		Container&lt;T&gt; c2(<span class="built_in">std</span>::move(c));</span><br><span class="line">		c1.swap(c2);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;；</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</span><br><span class="line"><span class="keyword">using</span> Vec = <span class="built_in">vector</span>&lt;T, allocator&lt;T&gt;&gt;; <span class="comment">//这部分不能声明在函数内部，只能声明在函数外</span></span><br><span class="line"></span><br><span class="line">XCIs&lt;<span class="built_in">string</span>, Vec&gt; c1;</span><br><span class="line">XCIs&lt;<span class="keyword">int</span>, Vect&gt; c2;</span><br></pre></td></tr></table></figure>
<h3 id="Type-Alias-类型别名"><a href="#Type-Alias-类型别名" class="headerlink" title="Type Alias(类型别名)"></a>Type Alias(类型别名)</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//两者等价</span></span><br><span class="line"><span class="function">typederf <span class="title">void</span><span class="params">(*func)</span><span class="params">(<span class="keyword">int</span>, <span class="keyword">int</span>)</span></span>;</span><br><span class="line"><span class="keyword">using</span> func = <span class="keyword">void</span>(*)(<span class="keyword">int</span>, <span class="keyword">int</span>);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">example</span><span class="params">(<span class="keyword">int</span>, <span class="keyword">int</span>)</span></span>&#123;&#125;</span><br><span class="line">func fn = example;</span><br></pre></td></tr></table></figure>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;typenem T&gt;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Container</span>&#123;</span></span><br><span class="line">    <span class="keyword">using</span> value_type = T; <span class="comment">//等同于 typedef T value_type</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> Cntr&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fn2</span><span class="params">(<span class="keyword">const</span> Cntr &amp; c)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">typename</span> Cntr::value_type n;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>类型别名中，<code>typedef</code>和<code>using</code>两种别名没有区别。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//模板别名</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="class"><span class="keyword">class</span> <span class="title">CharT</span>&gt; </span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">mystring</span> = <span class="title">std</span>:</span>:basic_string&lt;charT, Std::char_traits&lt;CharT&gt;&gt;;</span><br><span class="line"></span><br><span class="line">mystring&lt;<span class="keyword">char</span>&gt; str;</span><br></pre></td></tr></table></figure>
<p><code>&lt;string&gt;</code>和<code>&lt;string_fwd.h&gt;</code>都有一下<code>typedef</code>： </p>
<p><code>typedef basic_string&lt;char&gt; string;</code></p>
<h3 id="using"><a href="#using" class="headerlink" title="using"></a>using</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">using</span> <span class="built_in">std</span>::<span class="built_in">cout</span>;</span><br><span class="line"><span class="keyword">using</span> func = <span class="keyword">void</span>(*)(<span class="keyword">int</span>,<span class="keyword">int</span>);</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="class"><span class="keyword">class</span> <span class="title">CharT</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">template</span> &lt;class CharT&gt; </span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">mystring</span> = <span class="title">std</span>:</span>:basic_string&lt;charT, Std::char_traits&lt;CharT&gt;&gt;;</span><br></pre></td></tr></table></figure>
<h3 id="noexcept"><a href="#noexcept" class="headerlink" title="noexcept"></a>noexcept</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">foo</span><span class="params">()</span> <span class="keyword">noexcept</span></span>; <span class="comment">//表示这个函数不会丢出异常</span></span><br><span class="line"><span class="comment">//等同于</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">foo</span><span class="params">()</span> <span class="title">noexcept</span><span class="params">(<span class="literal">true</span>)</span></span>;</span><br></pre></td></tr></table></figure>
<p>如果foo()的异常没有被处理，foo()会抛出异常给调用其的函数。如果一直没有处理，最后调用<code>std::terminate()</code>终止。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">void swap(Type &amp; x, Type &amp; y) noexcept(noexcept(x.swap(y)))&#123;</span><br><span class="line">    x.swap(y);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我们必须通知C++(特别是<code>std::vector</code>)，异构构造函数和移动赋值拷贝构造函数不抛出异常。然后，<code>vector</code>动态增大时，移动构造函数会被调用。如果构造函数没有noexcept，<code>std::vector</code>就不能使用它，因为它不能确保移动构造函数不报错。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyString</span>&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">char</span> * _data;</span><br><span class="line">    <span class="keyword">size_t</span> _len;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    MyString(MyString &amp;&amp; str) <span class="keyword">noexcept</span></span><br><span class="line">    	: _data(str._data), _len(str._len)&#123;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    MyString &amp; <span class="keyword">operator</span>=(MyString &amp;&amp; str)<span class="keyword">noexcept</span>&#123;</span><br><span class="line">        <span class="comment">//....</span></span><br><span class="line">        <span class="keyword">return</span> *<span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>如果类中有移动构造函数，必须在移动构造函数上noexcept。如果没有，将该类的对象放入vector容器中时，不会调用该移动构造函数，而会调用拷贝构造函数。</p>
<h3 id="override"><a href="#override" class="headerlink" title="override"></a>override</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Base</span>&#123;</span></span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">vfunc</span><span class="params">(<span class="keyword">float</span>)</span></span>&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Derived1</span> :</span> Base&#123;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">vfunc</span><span class="params">(<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">        <span class="comment">//创建了一个新函数</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>上面由于vfunc函数的参数写错了，所以不会重载。但是编译器也不会报错。</p>
<p>可以通过添加<code>override</code>关键字来指定一个函数必须是重载函数，如果不对就报错。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Derived2</span> :</span> Base&#123;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">vfunc</span><span class="params">(<span class="keyword">int</span>)</span> override</span>&#123;</span><br><span class="line">        <span class="comment">//Error</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">vfunc</span><span class="params">(<span class="keyword">float</span>)</span> override</span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="final"><a href="#final" class="headerlink" title="final"></a>final</h3><p>第一种用法用来规定类是不能被继承的。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Base1</span> <span class="title">final</span>&#123;</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Derived1</span> :</span> Base1&#123;&#125;; <span class="comment">//Error</span></span><br></pre></td></tr></table></figure>
<p>第二种用法用于修饰虚函数，规定虚函数不能被重写。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Base2</span>&#123;</span></span><br><span class="line">	<span class="function"><span class="keyword">virtual</span> <span class="title">voidf</span><span class="params">()</span> final</span>;  </span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Derived2</span> :</span> Base2&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">()</span></span>; <span class="comment">//Error</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="decltype"><a href="#decltype" class="headerlink" title="decltype"></a>decltype</h3><p>使用decltype关键字来得到一个表达式的类型。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span>&lt;<span class="built_in">string</span>, <span class="keyword">float</span>&gt; coll;</span><br><span class="line"><span class="keyword">decltype</span>(coll)::value_type elem; </span><br><span class="line"><span class="built_in">map</span>&lt;<span class="built_in">string</span>, <span class="keyword">float</span>&gt;::value_type elem;</span><br></pre></td></tr></table></figure>
<p>三个作用：</p>
<ul>
<li>用来声明返回类型</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//错误示范</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T1, <span class="keyword">typename</span> T2&gt;</span><br><span class="line"><span class="keyword">decltype</span>&lt;x+y&gt; add(T1 x, T2 y); <span class="comment">//编译无法通过</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//正确做法</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T1, <span class="keyword">typename</span> T2&gt;</span><br><span class="line">auto add(T1 x, T2 y) -&gt; decltype(x+y);</span><br></pre></td></tr></table></figure>
<p>这种做法跟lambda相似。</p>
<ul>
<li>元编程</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">test18_decltype</span><span class="params">(T obj)</span></span>&#123;</span><br><span class="line">    <span class="built_in">map</span>&lt;<span class="built_in">string</span>, <span class="keyword">float</span>&gt;::value_type elem1;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">map</span>&lt;<span class="built_in">string</span>, <span class="keyword">float</span>&gt; coll;</span><br><span class="line">    <span class="keyword">decltype</span>(coll)::value_type elem2;</span><br><span class="line">    </span><br><span class="line">    typedef typename decltype(obj)::iterator iType; //typename帮助编译器去确定这整个是一个typename,出现::就使用typename</span><br><span class="line">    <span class="keyword">typedef</span> <span class="keyword">typename</span> T::iterator iType;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">decltype</span>(obj) anotherObj(obj);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>传递lambda表达式的类型</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> cmp  = [](<span class="keyword">const</span> Person &amp; p1, <span class="keyword">const</span> Person &amp; p2)&#123;</span><br><span class="line">    <span class="keyword">return</span> p1.lastname()&lt;p2.lastname() || </span><br><span class="line">        (p1.lastname() == p2.lastname() &amp;&amp; p2.firstname() &lt; p2.firstname());</span><br><span class="line">	&#125;;</span><br><span class="line"><span class="built_in">set</span>::<span class="built_in">set</span>&lt;Person, <span class="keyword">decltype</span>(cmp)&gt; coll(cmp);</span><br></pre></td></tr></table></figure>
<p>对于lambda，我们旺旺只能对象，没有类型，要获取其类型，就需要借助decltype。</p>
<h3 id="lambda"><a href="#lambda" class="headerlink" title="lambda"></a>lambda</h3><p>C++11引入了lambda，允许实现内联函数。，可以被用来当作一个参数。lmbda改变了我们使用C++标准库的方式。</p>
<h4 id="最简单的形式"><a href="#最简单的形式" class="headerlink" title="最简单的形式"></a>最简单的形式</h4><p>下面定义了一个函数，没有名称，但是没法使用。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[]&#123;</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"hello lambda"</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">&#125;;<span class="comment">//没有意义</span></span><br></pre></td></tr></table></figure>
<p>如果先使用上面那样声明的lambda函数，得如下使用：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[]&#123;</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"hello lambda"</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">&#125;(); <span class="comment">//成功调用</span></span><br></pre></td></tr></table></figure>
<p>经常使用下面得方式：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> l = []&#123;</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"hello lambda"</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">...</span><br><span class="line">l(); <span class="comment">//成功调用</span></span><br></pre></td></tr></table></figure>
<p>lambda是一个函数的定义，可以定义在表达式或函数里面。</p>
<h4 id="完整的形式"><a href="#完整的形式" class="headerlink" title="完整的形式"></a>完整的形式</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[...](...) <span class="keyword">mutable</span> throwSpec -&gt; retType&#123;...&#125;</span><br><span class="line">外部变量 参数 可改动     异常      返回类型</span><br></pre></td></tr></table></figure>
<p>如果后面三个可选的都不存在，<code>()</code>可以不用写。如果其中一个存在，<code>（）</code>就必须写。</p>
<p>下面分析参数的三种情况：</p>
<ul>
<li>第一种</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> id = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">auto</span> f =[id]()<span class="keyword">mutable</span>&#123;</span><br><span class="line">	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"id: "</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>;:<span class="built_in">endl</span>;</span><br><span class="line">    ++id; <span class="comment">//OK ,因为有mutable</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">id = <span class="number">42</span>;</span><br><span class="line">f();</span><br><span class="line">f();</span><br><span class="line">f();</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">输出： id: <span class="number">0</span></span><br><span class="line">      id: <span class="number">1</span></span><br><span class="line">      id: <span class="number">2</span></span><br><span class="line">      <span class="number">42</span></span><br></pre></td></tr></table></figure>
<p>下面的函数对象跟上面的结果一样。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Functor</span>&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">int</span> id;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">operator</span><span class="params">()</span><span class="params">()</span></span>&#123;</span><br><span class="line">    	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"id: "</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>;:<span class="built_in">endl</span>;</span><br><span class="line">    	++id; </span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line">Functor f;</span><br></pre></td></tr></table></figure>
<ul>
<li>第二种</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> id = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">auto</span> f =[&amp;id](<span class="keyword">int</span> param)&#123;</span><br><span class="line">	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"id: "</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>;:<span class="built_in">endl</span>;</span><br><span class="line">    ++id; <span class="comment">//OK   </span></span><br><span class="line">&#125;</span><br><span class="line">id = <span class="number">42</span>;</span><br><span class="line">f();</span><br><span class="line">f();</span><br><span class="line">f();</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">输出： id: <span class="number">42</span></span><br><span class="line">      id: <span class="number">43</span></span><br><span class="line">      id: <span class="number">44</span></span><br><span class="line">      <span class="number">42</span></span><br></pre></td></tr></table></figure>
<ul>
<li>第三种</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> id = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">auto</span> f =[id]()&#123;</span><br><span class="line">	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"id: "</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>;:<span class="built_in">endl</span>;</span><br><span class="line">    ++id; <span class="comment">//Error， increment of read-only variable 'id'</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p> 其它使用方式：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> id = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">auto</span> f = [id]() <span class="keyword">mutable</span>&#123;</span><br><span class="line">   	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"id: "</span> &lt;&lt; id &lt;&lt; <span class="built_in">std</span>;:<span class="built_in">endl</span>;</span><br><span class="line">    ++id; <span class="comment">//OK   </span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> x = <span class="number">5</span>;</span><br><span class="line">    <span class="keyword">int</span> y = <span class="number">6</span>;  <span class="comment">//可以声明变量</span></span><br><span class="line">    <span class="keyword">return</span> id; <span class="comment">//可以返回数值</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> y = <span class="number">42</span>;</span><br><span class="line"><span class="keyword">int</span> x = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">auto</span> qq = [=,&amp;y]()&#123;...&#125;; <span class="comment">//=表示传递所有的外部对象，通过传值的方式，仅读</span></span><br></pre></td></tr></table></figure>
<p>编译器为lambda产生的代码像下面的样子：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> tobefound = <span class="number">5</span>;</span><br><span class="line"><span class="keyword">auto</span> lmabda1 = [tobefound](<span class="keyword">int</span> val)&#123; <span class="keyword">return</span> val == tobefound;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//编译器的动作类似于</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UnNamedLocalFunction</span>&#123;</span></span><br><span class="line">	<span class="keyword">int</span> localVar;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    UnNamedLocalFunction(<span class="keyword">int</span> var) : localVar(var)&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">operator</span><span class="params">(<span class="keyword">int</span> val)</span><span class="params">()</span></span>&#123;</span><br><span class="line">        reutrn val == localVar;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function">UnNamedLocalFunction <span class="title">lambda2</span><span class="params">(tobefound)</span></span>;</span><br><span class="line"><span class="keyword">bool</span> b1 = lambda1(<span class="number">5</span>);</span><br><span class="line"><span class="keyword">bool</span> b2 = lambda2(<span class="number">5</span>);</span><br></pre></td></tr></table></figure>
<p>lambda表达式是一个匿名的函数对象。因此，声明一个这样的类型，需要使用template或者auto。如果需要得到lambda表达式类型，需要使用decltype()。当我们需要传递一个lambda表达式当作一个哈希函数或者容器的排序准则，需要使用decltype()获取lambda表达式。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> cmp  = [](<span class="keyword">const</span> Person &amp; p1, <span class="keyword">const</span> Person &amp; p2)&#123;</span><br><span class="line">    <span class="keyword">return</span> p1.lastname()&lt;p2.lastname() || </span><br><span class="line">        (p1.lastname() == p2.lastname() &amp;&amp; p2.firstname() &lt; p2.firstname());</span><br><span class="line">	&#125;;</span><br><span class="line"><span class="built_in">set</span>::<span class="built_in">set</span>&lt;Person, <span class="keyword">decltype</span>(cmp)&gt; coll(cmp);</span><br><span class="line"></span><br><span class="line"><span class="comment">//set</span></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="class"><span class="keyword">class</span> <span class="title">Key</span>, <span class="title">class</span> <span class="title">Compare</span> = <span class="title">less</span>&lt;Key&gt;, <span class="title">class</span> <span class="title">Alloc</span> = <span class="title">alloc</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">class</span> <span class="title">set</span>&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	<span class="comment">//typedefs</span></span><br><span class="line">	<span class="keyword">typedef</span> Compare key_compare;</span><br><span class="line">	<span class="keyword">typedef</span> Compare value_compare;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">	<span class="keyword">typedef</span> rb_tree&lt;key_type, value_teype，</span><br><span class="line">			identity&lt;value_type&gt;,</span><br><span class="line">			key_compare, Alloc&gt; rep_type;</span><br><span class="line">    rep_type t;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	<span class="built_in">set</span>(): t(Compare()) &#123;&#125;</span><br><span class="line">	explicit set(const Compare &amp; comp): t(comp) &#123;&#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>从上面set类中可以看出，set的构造函数需要给一个比较大小的对象，而如果不给，会调用对象的默认构造函数。而由于lambda没有默认构造函数，所以后报错。于是，在使用lambda表达式作为容器中比较大小的对象时，一定要在构造函数中指明，即<code>coll(cmp)</code>。</p>
<p>在算法中使用lambda表达式：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vi &#123;<span class="number">5</span>, <span class="number">28</span>, <span class="number">50</span>, <span class="number">83</span>, <span class="number">70</span>, <span class="number">245</span>, <span class="number">96</span>, <span class="number">12</span>&#125;;</span><br><span class="line"><span class="keyword">int</span> x = <span class="number">30</span>;</span><br><span class="line"><span class="keyword">int</span> y = <span class="number">100</span>;</span><br><span class="line">vi.erase(remove_if(vi.being(), </span><br><span class="line">                   vi.end(), </span><br><span class="line">                   [x, y](<span class="keyword">int</span> n)&#123; <span class="keyword">return</span> x &lt; n &amp;&amp; n &lt; y; &#125;),</span><br><span class="line">         vi.end()</span><br><span class="line">        );</span><br></pre></td></tr></table></figure>
<h3 id="Variadic-Templates-参数可变模板，深入"><a href="#Variadic-Templates-参数可变模板，深入" class="headerlink" title="Variadic Templates(参数可变模板，深入)"></a>Variadic Templates(参数可变模板，深入)</h3><p>讨论的是模板：</p>
<ul>
<li>函数模板</li>
<li>类模板</li>
<li>成员模板（不重要）</li>
</ul>
<p>变化的是：template parameters</p>
<ul>
<li>参数个数：利用参数个数逐一递减来实现递归函数的调用</li>
<li>参数类型：利用参数个数逐一减少导致参数类型也逐一减少的特性，实现递归继承和递归复合，以class template完成。</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">()</span></span>&#123;&#125; <span class="comment">//注意该函数必须存在，而且要放在开头</span></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span>... Types&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">(<span class="keyword">const</span> T &amp; firstArg, <span class="keyword">const</span> Types&amp;... args)</span></span>&#123;</span><br><span class="line">	<span class="comment">//...</span></span><br><span class="line">	func(args...);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>七个例子：</p>
<ul>
<li>例一</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printX</span><span class="params">()</span></span>&#123; <span class="comment">//特化版本</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span>... Types&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printX</span><span class="params">(<span class="keyword">const</span> T&amp; firsArg, <span class="keyword">const</span> Type&amp;... Args)</span></span>&#123;<span class="comment">//这是一个特化版本</span></span><br><span class="line">	<span class="built_in">cout</span> &lt;&lt; firstArg &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">	printX(args...);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span>... Types&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printX</span><span class="params">(<span class="keyword">const</span> Types&amp;... args)</span></span>&#123; <span class="comment">//不存在二义性，这是一个泛化版本，所以永远不会被调用</span></span><br><span class="line"><span class="comment">/*....*/</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">printX(<span class="number">7.5</span>, <span class="string">"hello"</span>, <span class="built_in">bitset</span>&lt;<span class="number">16</span>&gt;(<span class="number">377</span>), <span class="number">42.1</span>);</span><br></pre></td></tr></table></figure>
<p>可以通过<code>sizeof...(args)</code>来获得args的大小。</p>
<ul>
<li>例二: 利用variadic template重写printf()</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printf</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *s)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (*s)&#123;</span><br><span class="line">        <span class="keyword">if</span> (*s == <span class="string">'%'</span> &amp;&amp;*(++s)!= <span class="string">'%'</span>)</span><br><span class="line">            <span class="keyword">throw</span> <span class="built_in">std</span>::logic_error(<span class="string">"extra arguments provided to printf!"</span>);</span><br><span class="line">       	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; *s++;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span>... Args&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printf</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> * s, T value, Args... args)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (*s)&#123;</span><br><span class="line">        <span class="keyword">if</span>(*s == <span class="string">'%'</span> &amp;&amp; *(++s) != <span class="string">'%'</span>)&#123;</span><br><span class="line">        	<span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; value;</span><br><span class="line">        	<span class="built_in">printf</span>(++s, args...); </span><br><span class="line">        	<span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; *s++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">throw</span> <span class="built_in">std</span>::logic_error(<span class="string">"extra arguments provided to printf!"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>例三：实现max检测一堆数据中最大的一个</li>
</ul>
<p>对于参数类型不变，个数可变的问题，采用如下方法：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> _ForwardIterator, <span class="keyword">typename</span> _Compare&gt;</span><br><span class="line">_ForWardIterator _max_element(ForwardIterator _first, _ForwardIterator _last, _Compare _comp)&#123;</span><br><span class="line">	<span class="keyword">if</span>(_first == _last)</span><br><span class="line">		<span class="keyword">return</span> _first;</span><br><span class="line">	_ForwardIterator _result = _first;</span><br><span class="line">	<span class="keyword">while</span>(++_first != _last)&#123;</span><br><span class="line">		<span class="keyword">if</span> (_comp(_result, _first))</span><br><span class="line">			_result = _first;</span><br><span class="line">		<span class="keyword">return</span> _result;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> _ForwardIterator&gt;</span><br><span class="line"><span class="keyword">inline</span> _<span class="function">ForwardIterator <span class="title">max_element</span><span class="params">(_ForwardIterator _first, _ForwardIterator _last)</span></span>&#123;</span><br><span class="line">	<span class="keyword">return</span> _max_element(_first, _last, _iter_less_iter);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">inline</span> _Iter_less_ite _iter_less_iter()&#123;</span><br><span class="line">	<span class="keyword">return</span> _Iter_less_iter();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> _<span class="title">Iter_less_iter</span>&#123;</span></span><br><span class="line">	<span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Iterator1, <span class="keyword">typename</span> _Iterator2&gt;</span><br><span class="line">	<span class="function"><span class="keyword">bool</span> <span class="title">operator</span><span class="params">()</span><span class="params">(_Iterator1 _it1, _Iterator2 _it2)</span> <span class="keyword">const</span></span>&#123;</span><br><span class="line">		<span class="keyword">return</span> *_it1 &lt; *_it2;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line"><span class="keyword">inline</span> _<span class="function">Tp <span class="title">max</span><span class="params">(<span class="built_in">initializer_list</span>&lt;_Tp&gt; _l)</span></span>&#123;</span><br><span class="line">	<span class="keyword">return</span> *max_element(_l.begin(), _l.end());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; max(&#123;<span class="number">57</span>, <span class="number">48</span>, <span class="number">60</span>,<span class="number">100</span>,<span class="number">20</span>,<span class="number">18</span>&#125;) &lt;&lt; <span class="built_in">endl</span>; <span class="comment">//必须使用&#123;&#125;，来匹配initializer_list</span></span><br></pre></td></tr></table></figure>
<ul>
<li>例四：实现max，希望接口不需要使用<code>{}</code></li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">maximun</span><span class="params">(<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> n;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span>... Args&gt;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">maximum</span><span class="params">(<span class="keyword">int</span> n, Args... args)</span></span>&#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="built_in">std</span>::max(n, maximum(args...)); <span class="comment">//利用标准库里面的函数max</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; maximum(<span class="number">100</span>,<span class="number">34</span>,<span class="number">12</span>,<span class="number">56</span>,<span class="number">222</span>) &lt;&lt; <span class="built_in">endl</span>;</span><br></pre></td></tr></table></figure>
<p>其实标准库的的max可以接收任意多个数的参数，不过得加上<code>{}</code>。</p>
<ul>
<li>例五：以不同的方式处理first元素和last元素</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span>... Args&gt;</span><br><span class="line">ostream &amp; <span class="keyword">operator</span>&lt;&lt;(ostream &amp; os, cosnt tuple&lt;Args...&gt;&amp; t)&#123;</span><br><span class="line">	os &lt;&lt; <span class="string">"["</span>;</span><br><span class="line">	PRINT_TUPLE&lt;<span class="number">0</span>, <span class="keyword">sizeof</span>...(Args), Args...&gt;::print(os, t);</span><br><span class="line">	<span class="keyword">return</span> os &lt;&lt; <span class="string">"]"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> IDX, <span class="keyword">int</span> MAx, <span class="keyword">typename</span>... Args&gt;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">PRINT_TUPLE</span>&#123;</span></span><br><span class="line">	<span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">(ostream&amp; os, <span class="keyword">const</span> tuple&lt;Args...&gt; &amp;t)</span></span>&#123;</span><br><span class="line">		os &lt;&lt; get&lt;IDX&gt;(t) &lt;&lt; (IDX+<span class="number">1</span>==MAX?<span class="string">""</span>:<span class="string">","</span>);</span><br><span class="line">		PRINT_TUPLE&lt;IDX+<span class="number">1</span>, MAX, Args...&gt;::print(os, t);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">int</span> MAX, <span class="keyword">typename</span>... Args&gt; <span class="comment">//边界条件</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">PRINT_TUPLE</span>&lt;MAX, MAX, Args&gt;&#123;</span></span><br><span class="line">	<span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="built_in">std</span>::ostream&amp; os, <span class="keyword">const</span> tuple&lt;Args..&gt; &amp; t)</span></span>&#123;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; make_tuple(<span class="number">7.5</span>, <span class="string">"hello"</span>, <span class="built_in">bitset</span>&lt;<span class="number">16</span>&gt;(<span class="number">377</span>),<span class="number">42</span>); </span><br><span class="line"></span><br><span class="line">输出：</span><br><span class="line">[<span class="number">7.5</span>, <span class="string">"hello"</span>, <span class="built_in">bitset</span>&lt;16&gt;(<span class="number">377</span>),<span class="number">42</span>] <span class="comment">//期望输出最后一个元素时，没有逗号</span></span><br></pre></td></tr></table></figure>
<ul>
<li>例六：递归继承，<code>tuple</code>的实现</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span>... Values&gt; <span class="class"><span class="keyword">class</span> <span class="title">tuple</span>;</span></span><br><span class="line"><span class="keyword">template</span>&lt;&gt; <span class="class"><span class="keyword">class</span> <span class="title">tuple</span>&lt;&gt;&#123;</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> Head, <span class="keyword">typename</span>... Tail&gt;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">tuple</span>&lt;Head, Tail...&gt; :</span> <span class="keyword">private</span> tuple&lt;Tail...&gt;&#123;</span><br><span class="line">	<span class="keyword">typedef</span> tuple&lt;Tail...&gt; inherited;</span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line">	Head m_head;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	tuple()&#123;&#125;</span><br><span class="line">	tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...)&#123;&#125;</span><br><span class="line">	</span><br><span class="line">    <span class="comment">//typename Head::type head() &#123; return m_head; &#125; //报错，多次一举</span></span><br><span class="line">    <span class="comment">//直接用Head作为返回类型</span></span><br><span class="line">    <span class="comment">//Head head() &#123; return m_head; &#125;</span></span><br><span class="line">    <span class="comment">//修改为</span></span><br><span class="line">    auto head() -&gt; decltype(m_head) &#123; return m_head; &#125;</span><br><span class="line">    <span class="function">inherited&amp; <span class="title">tail</span><span class="params">()</span> </span>&#123; <span class="keyword">return</span> *<span class="keyword">this</span>; &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">tuple&lt;<span class="keyword">int</span>, <span class="keyword">float</span>, <span class="built_in">string</span>&gt; t(<span class="number">4</span>, <span class="number">6.3</span>, <span class="string">"nico"</span>);</span><br></pre></td></tr></table></figure>
<p>具体原理图：</p>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805162438.png" alt=""></p>
<ul>
<li>例七：递归复合，内含一个成员，而不是采用继承。具体原理如下图：</li>
</ul>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805163657.png" alt=""></p>
<p>具体代码实现：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span>... Values&gt; <span class="class"><span class="keyword">class</span> <span class="title">tup</span>;</span></span><br><span class="line"><span class="keyword">template</span>&lt;&gt; <span class="class"><span class="keyword">class</span> <span class="title">tup</span>&lt;&gt;&#123;</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Head, <span class="keyword">typename</span>... Tail&gt;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">tup</span>&lt;Head, Tail&gt;&#123;</span></span><br><span class="line">	<span class="keyword">typedef</span> tup&lt;Tail...&gt; composited;</span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line">	composited m_tail;</span><br><span class="line">	Head m_head;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	tup()&#123;&#125;</span><br><span class="line">	tup(Head v, Tail... vtail) : m_tail(vtail), m_head(v) &#123;&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="function">Head <span class="title">head</span><span class="params">()</span></span>&#123;<span class="keyword">return</span> m_head;&#125;</span><br><span class="line">	<span class="function">composited&amp; <span class="title">tail</span><span class="params">()</span></span>&#123;<span class="keyword">return</span> m_tail; &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">tup&lt;<span class="keyword">int</span>, <span class="keyword">float</span>, <span class="built_in">string</span>&gt; it1(<span class="number">41</span>, <span class="number">6.3</span>, <span class="string">"nico"</span>);</span><br></pre></td></tr></table></figure>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>C++中所有关键字，并且C++11中的新关键字。</p>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805163412.png" alt=""></p>
<p>资料网站：</p>
<p><a href="http://www.cplusplus.com/" target="_blank" rel="noopener">http://www.cplusplus.com/</a></p>
<p><a href="https://www.cprogramming.com/" target="_blank" rel="noopener">https://www.cprogramming.com/</a></p>
<p><a href="https://en.cppreference.com/" target="_blank" rel="noopener">https://en.cppreference.com/</a></p>
<h2 id="标准库"><a href="#标准库" class="headerlink" title="标准库"></a>标准库</h2><p>在VS2017中，标准库在<code>VS\VC\Tools\MSVC\14.16.27023\include\</code>目录下。</p>
<h3 id="右值引用"><a href="#右值引用" class="headerlink" title="右值引用"></a>右值引用</h3><p>右值引用可以解决不必要的复制。当赋值的右手边是一个右值的话，左手边的对象可以“偷”右手边的对象，而不需要去执行分配一个独立内存，这样就实现了移动语义。</p>
<ul>
<li>左值：变量，可以接收赋值</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> a = <span class="number">9</span>；</span><br><span class="line"><span class="keyword">int</span> b = <span class="number">4</span>;</span><br><span class="line">a = b;</span><br><span class="line">b = a;</span><br><span class="line">a = a + b;</span><br><span class="line">a + b = <span class="number">42</span>; <span class="comment">//Error， a+b右值不能在赋值的左边</span></span><br></pre></td></tr></table></figure>
<ul>
<li>右值：临时对象，不能放在赋值左边</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">s1</span><span class="params">(<span class="string">"Hello"</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">s2</span><span class="params">(<span class="string">"World"</span>)</span></span>;</span><br><span class="line">s1 + s2 = s2; <span class="comment">//竟然可以通过编译</span></span><br><span class="line"><span class="built_in">string</span>() = <span class="string">"World"</span>; <span class="comment">//竟然也通过了编译</span></span><br></pre></td></tr></table></figure>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">complex</span>&lt;<span class="keyword">int</span>&gt; c1(<span class="number">3</span>,<span class="number">8</span>), x2(<span class="number">1</span>,<span class="number">0</span>);</span><br><span class="line">c1 + c2 = <span class="keyword">complex</span>&lt;<span class="keyword">int</span>&gt;(<span class="number">4</span>,<span class="number">9</span>); <span class="comment">//竟然也可以</span></span><br><span class="line"><span class="keyword">complex</span>&lt;<span class="keyword">int</span>&gt;() =  <span class="keyword">complex</span>&lt;<span class="keyword">int</span>&gt;(<span class="number">4</span>,<span class="number">9</span>); <span class="comment">//竟然也可以</span></span><br></pre></td></tr></table></figure>
<p>以上是两种特殊的情况！！！</p>
<p>不能对右值取地址：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fo</span><span class="params">()</span> </span>&#123;<span class="keyword">return</span> <span class="number">4</span>;&#125;</span><br><span class="line"><span class="keyword">int</span> x = foo();</span><br><span class="line"><span class="keyword">int</span> * p = &amp;foo(); <span class="comment">//Error，对右值取其地址，是不可以的</span></span><br><span class="line">foo() = <span class="number">7</span>; <span class="comment">//Error</span></span><br></pre></td></tr></table></figure>
<p>容器插入元素，可以使用移动语义：</p>
<p>使用移动语义（移动构造，移动赋值，std::move），之前的指针就无法使用。</p>
<p><code>std::move()</code>可以将一个左值转换为一个右值（只有变量（左值）后面不会再用到才能使用std::move，因为通过std::move后左值将会失效 。），然后可以自动调用移动构造函数或移动赋值函数。</p>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805194857.png" alt=""></p>
<p>在C++2.0之前，insert只有一种版本。在2.0开始，有两种版本，增加了使用移动语义的版本。</p>
<h3 id="移动语义"><a href="#移动语义" class="headerlink" title="移动语义"></a>移动语义</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyString</span>&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">char</span> * _data;</span><br><span class="line">   	...</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">//copy assignment</span></span><br><span class="line">    MyString &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> MyString &amp;str)&#123;</span><br><span class="line">        ...</span><br><span class="line">        <span class="keyword">return</span> *<span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//move assignment</span></span><br><span class="line">    <span class="function">MyString &amp; <span class="title">operator</span><span class="params">(MyString &amp;&amp; str)</span> <span class="keyword">noexcept</span></span>&#123;</span><br><span class="line">        <span class="comment">//....</span></span><br><span class="line">        <span class="keyword">return</span> *<span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="完美转移"><a href="#完美转移" class="headerlink" title="完美转移"></a>完美转移</h3><p>不完美的转移：</p>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190805200019.png" alt=""></p>
<p><code>forward(move(a))</code>调用移动语义版本的<code>forward(int&amp;&amp; i)</code>，然后再调用process函数的时候，i变成了左值，就会调用<code>process(int &amp; i)</code>，即拷贝构造函数，而不是移动语义的函数了，这不是我们所期望的。我们期望一直调用的都是移动语义的函数。</p>
<p>完美的转移允许我们编写一个有n各参数的简单函数，能够传递这些参数给另一个函数，并且保留了这些参数的性质，即移动语义、const、左值或右值。</p>
<p>如果先做到完美的转移，必须要调用forward。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T1, <span class="keyword">typename</span> T2&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">functionA</span><span class="params">(T1&amp;&amp; t1, T2&amp;&amp; t2)</span></span>&#123;</span><br><span class="line">	functionB(<span class="built_in">std</span>::forward&lt;T1&gt;(t1), <span class="built_in">std</span>::forward&lt;T2&gt;(t2));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190806130246.png" alt=""></p>
<p>实现一个具有移动语义的类：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyString</span>&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> Dctor;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> Ctor;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> CCtor;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> MCtor;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> CAsgn;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> MAsgn;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> Dtor;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">char</span> * _data;</span><br><span class="line">    <span class="keyword">size_t</span> _len;</span><br><span class="line">   	<span class="keyword">void</span> _init_data(<span class="keyword">const</span> <span class="keyword">char</span> *s)&#123;</span><br><span class="line">        _data = <span class="keyword">new</span> <span class="keyword">char</span>[_len+<span class="number">1</span>];</span><br><span class="line">        <span class="built_in">memcpy</span>(_data, s, _len);</span><br><span class="line">        _data[_len] = <span class="string">'\0'</span>;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">//默认构造</span></span><br><span class="line">    MyString() : _data(<span class="literal">NULL</span>), _len(<span class="number">0</span>) &#123; ++DCtor; &#125;</span><br><span class="line">    <span class="comment">//构造函数</span></span><br><span class="line">    Mystring(<span class="keyword">const</span> <span class="keyword">char</span> *p) : _len(<span class="built_in">strlen</span>(p))&#123;</span><br><span class="line">        ++Ctor;</span><br><span class="line">        _init_data(p);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//拷贝构造</span></span><br><span class="line">    MString(<span class="keyword">const</span> MyString &amp; str) : _len(str._len)&#123;</span><br><span class="line">        ++CCtor;</span><br><span class="line">        _init_data(str._data);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//移动构造</span></span><br><span class="line">    MyString(MyString &amp;&amp; str) <span class="keyword">noexcept</span> </span><br><span class="line">    	: _data(str._data), _len(str._len)&#123;</span><br><span class="line">        ++MCtor;</span><br><span class="line">        str._len = <span class="number">0</span>;</span><br><span class="line">        str._data = <span class="literal">NULL</span>; <span class="comment">//重要</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//拷贝赋值</span></span><br><span class="line">	MyString &amp; <span class="keyword">operator</span>=(<span class="keyword">const</span> MyString &amp; str)    &#123;</span><br><span class="line">        ++CASgn;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span> != &amp;str)&#123;</span><br><span class="line">            <span class="keyword">if</span> (_data) <span class="keyword">delete</span> _data;</span><br><span class="line">            _len = str._len;</span><br><span class="line">            _init_data(str._data);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;&#125;</span><br><span class="line">        <span class="keyword">return</span> *<span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//移动赋值</span></span><br><span class="line">    MyString &amp; <span class="keyword">operator</span>=(MyStirng &amp;&amp; str) <span class="keyword">noexcept</span>&#123;</span><br><span class="line">        ++MAsgn;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span> != &amp;str)&#123;</span><br><span class="line">            <span class="keyword">if</span> (_data) <span class="keyword">delete</span> _data;</span><br><span class="line">            _len = str._len;</span><br><span class="line">            _data = str._data; <span class="comment">//移动</span></span><br><span class="line">            str._len = <span class="number">0</span>;</span><br><span class="line">            str._data = <span class="literal">NULL</span>: <span class="comment">//重要</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//析构函数</span></span><br><span class="line">    <span class="keyword">virtual</span> ~MStirng()&#123;</span><br><span class="line">        ++Dtor;</span><br><span class="line">        <span class="keyword">if</span> (_data)</span><br><span class="line">            <span class="keyword">delete</span> _data;</span><br><span class="line">    &#125;</span><br><span class="line">   <span class="keyword">bool</span> <span class="keyword">operator</span>&lt;(<span class="keyword">const</span> Mystring &amp; rhs) <span class="keyword">const</span>&#123;</span><br><span class="line">       <span class="keyword">return</span> <span class="built_in">string</span>(<span class="keyword">this</span>-&gt;_data) &lt; <span class="built_in">string</span>(rhs._data);</span><br><span class="line">   &#125;</span><br><span class="line">    <span class="keyword">bool</span> <span class="keyword">operator</span>==(<span class="keyword">const</span> MyString &amp; rhs) <span class="keyword">const</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">string</span>(<span class="keyword">this</span>-&gt;_data) == <span class="built_in">string</span>(rhs._data);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">char</span> * <span class="title">get</span><span class="params">()</span> <span class="keyword">const</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> _data;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">int</span> MyString::Dctor = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> MyString::Ctor = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> MyString::CCtor = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> MyString::MCtor = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> MyString::CAsgn = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> MyString::MAsgn = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> MyString::Dtor = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="built_in">std</span>&#123;</span><br><span class="line">    <span class="keyword">template</span>&lt;&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>&lt;MyString&gt;&#123;</span></span><br><span class="line">    	<span class="keyword">size_t</span> <span class="keyword">operator</span>(<span class="keyword">const</span> MyString &amp; s) <span class="keyword">const</span> <span class="keyword">noexcept</span>&#123;</span><br><span class="line">    		<span class="keyword">return</span> hash&lt;<span class="built_in">string</span>&gt;()(<span class="built_in">string</span>(s.get()));</span><br><span class="line">    	&#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> M, <span class="keyword">typename</span> NM&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">test_moveable</span><span class="params">(M c1, NM c2, <span class="keyword">long</span> &amp; value)</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> buf[<span class="number">10</span>];</span><br><span class="line">	<span class="comment">//测试moveable</span></span><br><span class="line">	<span class="keyword">typedef</span> <span class="keyword">typename</span> iterator_traits&lt;<span class="keyword">typename</span> M::iterator&gt;::value_type Vtype;</span><br><span class="line">	<span class="keyword">for</span> (<span class="keyword">long</span> i = <span class="number">0</span>; i &lt; value; ++i)&#123;</span><br><span class="line">		<span class="built_in">snprintf</span>(buf, <span class="number">10</span>, <span class="string">"%d"</span>, rand());</span><br><span class="line">		<span class="keyword">auto</span> ite = c.end();</span><br><span class="line">		c.insert(ite, Vtype(buf));</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function">M <span class="title">c1</span><span class="params">(c)</span></span>;</span><br><span class="line">	M c2(std::move(c1));</span><br><span class="line">	c1.swap(c2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="容器"><a href="#容器" class="headerlink" title="容器"></a>容器</h2><h3 id="array"><a href="#array" class="headerlink" title="array"></a>array</h3><p>内部就是一个C++的数组，只不过被包装成类，但是没有构造函数和析构函数（因为数组没有这些），提供了容器应该有的接口，比如end(), begin()等。</p>
<h3 id="hashtable"><a href="#hashtable" class="headerlink" title="hashtable"></a>hashtable</h3><p>hashtable的篮子个数是采用vector实现，所以是会动态增加的。</p>
<p>如果一个链表太长（链表节点的数量等于篮子的数量），就将篮子数量加倍，重新计算(rehashing)。</p>
<p>元素在篮子的位置计算方式：元素的值除以篮子数量得到的余数就是所在的位置。</p>
<p><img src="https://raw.githubusercontent.com/zxpgo/images/master/img/20190806134854.png" alt=""></p>
<h3 id="hash-functions"><a href="#hash-functions" class="headerlink" title="hash functions"></a>hash functions</h3><p><code>functional_hash.h</code>头文件给出了所有了hash functions。源代码如下：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> _FUNCTIONAL_HASH_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> _FUNCTIONAL_HASH_H 1</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> GCC system_header</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;bits/hash_bytes.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="built_in">std</span> _GLIBCXX_VISIBILITY(<span class="keyword">default</span>)</span><br><span class="line">&#123;</span><br><span class="line">_GLIBCXX_BEGIN_NAMESPACE_VERSION</span><br><span class="line"></span><br><span class="line">  <span class="comment">/** @defgroup hashes Hashes</span></span><br><span class="line"><span class="comment">   *  @ingroup functors</span></span><br><span class="line"><span class="comment">   *</span></span><br><span class="line"><span class="comment">   *   Hashing functors taking a variable type and returning a @c std::size_t.</span></span><br><span class="line"><span class="comment">   *</span></span><br><span class="line"><span class="comment">   *  @&#123;</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Result, <span class="keyword">typename</span> _Arg&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> __<span class="title">hash_base</span></span></span><br><span class="line"><span class="class">    &#123;</span></span><br><span class="line">      <span class="keyword">typedef</span> _Result     result_type;</span><br><span class="line">      <span class="keyword">typedef</span> _Arg      argument_type;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Primary class template hash.</span></span><br><span class="line">  <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Partial specializations for pointer types.</span></span><br><span class="line">  <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>&lt;_Tp*&gt; :</span> <span class="keyword">public</span> __hash_base&lt;<span class="keyword">size_t</span>, _Tp*&gt;</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="keyword">size_t</span></span><br><span class="line">      <span class="keyword">operator</span>()(_Tp* __p) <span class="keyword">const</span> <span class="keyword">noexcept</span></span><br><span class="line">      &#123; <span class="keyword">return</span> <span class="keyword">reinterpret_cast</span>&lt;<span class="keyword">size_t</span>&gt;(__p); &#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Explicit specializations for integer types.</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> _Cxx_hashtable_define_trivial_hash(_Tp) 	\</span></span><br><span class="line">  <span class="keyword">template</span>&lt;&gt;						\</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>&lt;_Tp&gt; :</span> <span class="keyword">public</span> __hash_base&lt;<span class="keyword">size_t</span>, _Tp&gt;  \</span><br><span class="line">    &#123;                                                   \</span><br><span class="line">      <span class="keyword">size_t</span>                                            \</span><br><span class="line">      <span class="keyword">operator</span>()(_Tp __val) <span class="keyword">const</span> <span class="keyword">noexcept</span>              \</span><br><span class="line">      &#123; <span class="keyword">return</span> <span class="keyword">static_cast</span>&lt;<span class="keyword">size_t</span>&gt;(__val); &#125;            \</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for bool.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">bool</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for char.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">char</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for signed char.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">signed</span> <span class="keyword">char</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for unsigned char.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">unsigned</span> <span class="keyword">char</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for wchar_t.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">wchar_t</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for char16_t.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">char16_t</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for char32_t.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">char32_t</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for short.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">short</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for int.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">int</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for long.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">long</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for long long.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">long</span> <span class="keyword">long</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for unsigned short.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">unsigned</span> <span class="keyword">short</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for unsigned int.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">unsigned</span> <span class="keyword">int</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for unsigned long.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">unsigned</span> <span class="keyword">long</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Explicit specialization for unsigned long long.</span></span><br><span class="line">  _Cxx_hashtable_define_trivial_hash(<span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span>)</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">undef</span> _Cxx_hashtable_define_trivial_hash</span></span><br><span class="line"></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> _<span class="title">Hash_impl</span></span></span><br><span class="line"><span class="class">  &#123;</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">size_t</span></span><br><span class="line">    hash(<span class="keyword">const</span> <span class="keyword">void</span>* __ptr, <span class="keyword">size_t</span> __clength,</span><br><span class="line">	 <span class="keyword">size_t</span> __seed = <span class="keyword">static_cast</span>&lt;<span class="keyword">size_t</span>&gt;(<span class="number">0xc70f6907</span>UL))</span><br><span class="line">    &#123; <span class="keyword">return</span> _Hash_bytes(__ptr, __clength, __seed); &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line">      <span class="keyword">static</span> <span class="keyword">size_t</span></span><br><span class="line">      hash(<span class="keyword">const</span> _Tp&amp; __val)</span><br><span class="line">      &#123; <span class="keyword">return</span> hash(&amp;__val, <span class="keyword">sizeof</span>(__val)); &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line">      <span class="keyword">static</span> <span class="keyword">size_t</span></span><br><span class="line">      __hash_combine(<span class="keyword">const</span> _Tp&amp; __val, <span class="keyword">size_t</span> __hash)</span><br><span class="line">      &#123; <span class="keyword">return</span> hash(&amp;__val, <span class="keyword">sizeof</span>(__val), __hash); &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> _<span class="title">Fnv_hash_impl</span></span></span><br><span class="line"><span class="class">  &#123;</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">size_t</span></span><br><span class="line">    hash(<span class="keyword">const</span> <span class="keyword">void</span>* __ptr, <span class="keyword">size_t</span> __clength,</span><br><span class="line">	 <span class="keyword">size_t</span> __seed = <span class="keyword">static_cast</span>&lt;<span class="keyword">size_t</span>&gt;(<span class="number">2166136261U</span>L))</span><br><span class="line">    &#123; <span class="keyword">return</span> _Fnv_hash_bytes(__ptr, __clength, __seed); &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line">      <span class="keyword">static</span> <span class="keyword">size_t</span></span><br><span class="line">      hash(<span class="keyword">const</span> _Tp&amp; __val)</span><br><span class="line">      &#123; <span class="keyword">return</span> hash(&amp;__val, <span class="keyword">sizeof</span>(__val)); &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Tp&gt;</span><br><span class="line">      <span class="keyword">static</span> <span class="keyword">size_t</span></span><br><span class="line">      __hash_combine(<span class="keyword">const</span> _Tp&amp; __val, <span class="keyword">size_t</span> __hash)</span><br><span class="line">      &#123; <span class="keyword">return</span> hash(&amp;__val, <span class="keyword">sizeof</span>(__val), __hash); &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Specialization for float.</span></span><br><span class="line">  <span class="keyword">template</span>&lt;&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>&lt;float&gt; :</span> <span class="keyword">public</span> __hash_base&lt;<span class="keyword">size_t</span>, <span class="keyword">float</span>&gt;</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="keyword">size_t</span></span><br><span class="line">      <span class="keyword">operator</span>()(<span class="keyword">float</span> __val) <span class="keyword">const</span> <span class="keyword">noexcept</span></span><br><span class="line">      &#123;</span><br><span class="line">	<span class="comment">// 0 and -0 both hash to zero.</span></span><br><span class="line">	<span class="keyword">return</span> __val != <span class="number">0.0f</span> ? <span class="built_in">std</span>::_Hash_impl::hash(__val) : <span class="number">0</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Specialization for double.</span></span><br><span class="line">  <span class="keyword">template</span>&lt;&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>&lt;double&gt; :</span> <span class="keyword">public</span> __hash_base&lt;<span class="keyword">size_t</span>, <span class="keyword">double</span>&gt;</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="keyword">size_t</span></span><br><span class="line">      <span class="keyword">operator</span>()(<span class="keyword">double</span> __val) <span class="keyword">const</span> <span class="keyword">noexcept</span></span><br><span class="line">      &#123;</span><br><span class="line">	<span class="comment">// 0 and -0 both hash to zero.</span></span><br><span class="line">	<span class="keyword">return</span> __val != <span class="number">0.0</span> ? <span class="built_in">std</span>::_Hash_impl::hash(__val) : <span class="number">0</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// Specialization for long double.</span></span><br><span class="line">  <span class="keyword">template</span>&lt;&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">hash</span>&lt;long double&gt;</span></span><br><span class="line"><span class="class">    :</span> <span class="keyword">public</span> __hash_base&lt;<span class="keyword">size_t</span>, <span class="keyword">long</span> <span class="keyword">double</span>&gt;</span><br><span class="line">    &#123;</span><br><span class="line">      _GLIBCXX_PURE <span class="keyword">size_t</span></span><br><span class="line">      <span class="keyword">operator</span>()(<span class="keyword">long</span> <span class="keyword">double</span> __val) <span class="keyword">const</span> <span class="keyword">noexcept</span>;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// @&#125; group hashes</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// Hint about performance of hash functor. If not fast the hash based</span></span><br><span class="line">  <span class="comment">// containers will cache the hash code.</span></span><br><span class="line">  <span class="comment">// Default behavior is to consider that hasher are fast unless specified</span></span><br><span class="line">  <span class="comment">// otherwise.</span></span><br><span class="line">  <span class="keyword">template</span>&lt;<span class="keyword">typename</span> _Hash&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> __<span class="title">is_fast_hash</span> :</span> <span class="keyword">public</span> <span class="built_in">std</span>::true_type</span><br><span class="line">    &#123; &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">template</span>&lt;&gt;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> __<span class="title">is_fast_hash</span>&lt;hash&lt;long double&gt;&gt; :</span> <span class="keyword">public</span> <span class="built_in">std</span>::false_type</span><br><span class="line">    &#123; &#125;;</span><br><span class="line"></span><br><span class="line">_GLIBCXX_END_NAMESPACE_VERSION</span><br><span class="line">&#125; <span class="comment">// namespace</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span> <span class="comment">// _FUNCTIONAL_HASH_H</span></span></span><br></pre></td></tr></table></figure>
<h2 id="tuple"><a href="#tuple" class="headerlink" title="tuple"></a>tuple</h2><p><a href="https://www.zxpblog.cn/2019/05/20/STL%E5%AD%A6%E4%B9%A0/" target="_blank" rel="noopener">https://www.zxpblog.cn/2019/05/20/STL%E5%AD%A6%E4%B9%A0/</a> </p>

      
    </div>
    
    
    

    
      <div>
        <div id="wechat_subscriber" style="display: block; padding: 10px 0; margin: 20px auto; width: 100%; text-align: center">
    <img id="wechat_subscriber_qcode" src="/images/wechat-qcode.jpg" alt="zxp wechat" style="width: 200px; max-width: 100%;"/>
    <div>欢迎关注微信公众号！</div>
</div>

      </div>
    

    
      <div>
        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
  <div></div>
  <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
    <span>打赏</span>
  </button>
  <div id="QR" style="display: none;">

    
      <div id="wechat" style="display: inline-block">
        <img id="wechat_qr" src="/images/WeChatpay.jpg" alt="zxp 微信支付"/>
        <p>微信支付</p>
      </div>
    

    
      <div id="alipay" style="display: inline-block">
        <img id="alipay_qr" src="/images/Alipay.jpg" alt="zxp 支付宝"/>
        <p>支付宝</p>
      </div>
    

    

  </div>
</div>

      </div>
    

    
      <div>
        <ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者：</strong>
    zxp
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="https://zxpgo.github.io/2019/08/03/C++2.0新特性/" title="C++2.0(11)新特性">https://zxpgo.github.io/2019/08/03/C++2.0新特性/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>
    本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/" rel="external nofollow" target="_blank">CC BY-NC-SA 3.0</a> 许可协议。转载请注明出处！
  </li>
</ul>

      </div>
    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tag/C/" rel="tag"># C++</a>
          
        </div>
      

      
      
        <div class="post-widgets">
        

        

        
          
          <div id="needsharebutton-postbottom">
            <span class="btn">
              <i class="fa fa-share-alt" aria-hidden="true"></i>
            </span>
          </div>
        
        </div>
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2019/08/02/设计模式/" rel="next" title="C++版设计模式">
                <i class="fa fa-chevron-left"></i> C++版设计模式
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2019/08/04/k8s/" rel="prev" title="k8s基本概念">
                k8s基本概念 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="lv-container" data-id="city" data-uid="MTAyMC8zODgxNC8xNTM0Mg=="></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/images/avatar.gif"
                alt="zxp" />
            
              <p class="site-author-name" itemprop="name">zxp</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">176</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">16</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">48</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          
            <div class="feed-link motion-element">
              <a href="/atom.xml" rel="alternate">
                <i class="fa fa-rss"></i>
                RSS
              </a>
            </div>
          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://blog.csdn.net/qq_25774883" target="_blank" title="CSDN">
                      
                        <i class="fa fa-fw fa-globe"></i>CSDN</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/zxpgo/zxpgo" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-globe"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://www.linkedin.com/feed/" target="_blank" title="LinkedIn">
                      
                        <i class="fa fa-fw fa-globe"></i>LinkedIn</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="1165772354@qq.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
            </div>
          

          
          

          
          
            <div class="links-of-blogroll motion-element links-of-blogroll-inline">
              <div class="links-of-blogroll-title">
                <i class="fa  fa-fw fa-link"></i>
                友情链接
              </div>
              <ul class="links-of-blogroll-list">
                
                  <li class="links-of-blogroll-item">
                    <a href="http://theme-next.iissnan.com" title="Next主题" target="_blank">Next主题</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="http://blog.rexking6.top" title="青爷博客" target="_blank">青爷博客</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://me.csdn.net/download/qq_25774883" title="CSDN下载" target="_blank">CSDN下载</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://www.livere.com/" title="来必力" target="_blank">来必力</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://tongji.baidu.com/web/welcome/login" title="百度统计" target="_blank">百度统计</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://leancloud.cn/" title="LeanCloud" target="_blank">LeanCloud</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="http://ibruce.info/2015/04/04/busuanzi/" title="不蒜子" target="_blank">不蒜子</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://leetcode-cn.com/" title="LeetCode" target="_blank">LeetCode</a>
                  </li>
                
              </ul>
            </div>
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#C-演化"><span class="nav-number">1.</span> <span class="nav-text">C++演化</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Header-files"><span class="nav-number">2.</span> <span class="nav-text">Header files</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#语言"><span class="nav-number">3.</span> <span class="nav-text">语言</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Variadic-Templates-参数可变模板"><span class="nav-number">3.1.</span> <span class="nav-text">Variadic Templates(参数可变模板)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#模板表达式中的空格"><span class="nav-number">3.2.</span> <span class="nav-text">模板表达式中的空格</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#nullptr和std-nullptr-t"><span class="nav-number">3.3.</span> <span class="nav-text">nullptr和std::nullptr_t</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#auto"><span class="nav-number">3.4.</span> <span class="nav-text">auto</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Uniform-Initialization-一致性初始化"><span class="nav-number">3.5.</span> <span class="nav-text">Uniform Initialization(一致性初始化)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Initializer-lists"><span class="nav-number">3.6.</span> <span class="nav-text">Initializer lists</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#initializer-list-lt-gt"><span class="nav-number">3.7.</span> <span class="nav-text">initializer_list&lt;&gt;</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#explicit"><span class="nav-number">3.8.</span> <span class="nav-text">explicit</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#基于范围的for"><span class="nav-number">3.9.</span> <span class="nav-text">基于范围的for</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#default和-delete"><span class="nav-number">3.10.</span> <span class="nav-text">=default和=delete</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Alias-Template-别名模板，template-typedef"><span class="nav-number">3.11.</span> <span class="nav-text">Alias Template(别名模板，template typedef)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#template-template-parameter-模板模板参数"><span class="nav-number">3.12.</span> <span class="nav-text">template template parameter(模板模板参数)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Type-Alias-类型别名"><span class="nav-number">3.13.</span> <span class="nav-text">Type Alias(类型别名)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#using"><span class="nav-number">3.14.</span> <span class="nav-text">using</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#noexcept"><span class="nav-number">3.15.</span> <span class="nav-text">noexcept</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#override"><span class="nav-number">3.16.</span> <span class="nav-text">override</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#final"><span class="nav-number">3.17.</span> <span class="nav-text">final</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#decltype"><span class="nav-number">3.18.</span> <span class="nav-text">decltype</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#lambda"><span class="nav-number">3.19.</span> <span class="nav-text">lambda</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#最简单的形式"><span class="nav-number">3.19.1.</span> <span class="nav-text">最简单的形式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#完整的形式"><span class="nav-number">3.19.2.</span> <span class="nav-text">完整的形式</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Variadic-Templates-参数可变模板，深入"><span class="nav-number">3.20.</span> <span class="nav-text">Variadic Templates(参数可变模板，深入)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#总结"><span class="nav-number">3.21.</span> <span class="nav-text">总结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#标准库"><span class="nav-number">4.</span> <span class="nav-text">标准库</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#右值引用"><span class="nav-number">4.1.</span> <span class="nav-text">右值引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#移动语义"><span class="nav-number">4.2.</span> <span class="nav-text">移动语义</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#完美转移"><span class="nav-number">4.3.</span> <span class="nav-text">完美转移</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#容器"><span class="nav-number">5.</span> <span class="nav-text">容器</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#array"><span class="nav-number">5.1.</span> <span class="nav-text">array</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#hashtable"><span class="nav-number">5.2.</span> <span class="nav-text">hashtable</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#hash-functions"><span class="nav-number">5.3.</span> <span class="nav-text">hash functions</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#tuple"><span class="nav-number">6.</span> <span class="nav-text">tuple</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div>
<script async src="https//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<i class="fa fa-user-md"></i><span id="busuanzi_container_site_pv" style='display:none'>
    本站总访问量 <span id="busuanzi_value_site_pv"></span> 
    <span class="post-meta-divider">|</span>
</span>
<span id="busuanzi_container_site_uv" style='display:none'>
    访问人数 <span id="busuanzi_value_site_uv"></span>
</span>
</div>


<script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

<div class="copyright">&copy; 2018-8 &mdash; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-"></i> Power by 
  </span>
  <span class="author" itemprop="copyrightHolder">zxp</span>
  
  
</div>









        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    
      <div id="needsharebutton-float">
        <span class="btn">
          <i class="fa fa-share-alt" aria-hidden="true"></i>
        </span>
      </div>
    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  




  
  <div id="lv-container" data-uid="MTAyMC8zODgxNC8xNTM0Mg==">
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
	</div>
  











  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>





  

  
  <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
  <script>AV.initialize("2AyV3DKioBSdoryrFLRohzjB-gzGzoHsz", "XynedcHyJCVCrTfbD4yYnodo");</script>
  <script>
    function showTime(Counter) {
      var query = new AV.Query(Counter);
      var entries = [];
      var $visitors = $(".leancloud_visitors");

      $visitors.each(function () {
        entries.push( $(this).attr("id").trim() );
      });

      query.containedIn('url', entries);
      query.find()
        .done(function (results) {
          var COUNT_CONTAINER_REF = '.leancloud-visitors-count';

          if (results.length === 0) {
            $visitors.find(COUNT_CONTAINER_REF).text(0);
            return;
          }

          for (var i = 0; i < results.length; i++) {
            var item = results[i];
            var url = item.get('url');
            var time = item.get('time');
            var element = document.getElementById(url);

            $(element).find(COUNT_CONTAINER_REF).text(time);
          }
          for(var i = 0; i < entries.length; i++) {
            var url = entries[i];
            var element = document.getElementById(url);
            var countSpan = $(element).find(COUNT_CONTAINER_REF);
            if( countSpan.text() == '') {
              countSpan.text(0);
            }
          }
        })
        .fail(function (object, error) {
          console.log("Error: " + error.code + " " + error.message);
        });
    }

    function addCount(Counter) {
      var $visitors = $(".leancloud_visitors");
      var url = $visitors.attr('id').trim();
      var title = $visitors.attr('data-flag-title').trim();
      var query = new AV.Query(Counter);

      query.equalTo("url", url);
      query.find({
        success: function(results) {
          if (results.length > 0) {
            var counter = results[0];
            counter.fetchWhenSave(true);
            counter.increment("time");
            counter.save(null, {
              success: function(counter) {
                var $element = $(document.getElementById(url));
                $element.find('.leancloud-visitors-count').text(counter.get('time'));
              },
              error: function(counter, error) {
                console.log('Failed to save Visitor num, with error message: ' + error.message);
              }
            });
          } else {
            var newcounter = new Counter();
            /* Set ACL */
            var acl = new AV.ACL();
            acl.setPublicReadAccess(true);
            acl.setPublicWriteAccess(true);
            newcounter.setACL(acl);
            /* End Set ACL */
            newcounter.set("title", title);
            newcounter.set("url", url);
            newcounter.set("time", 1);
            newcounter.save(null, {
              success: function(newcounter) {
                var $element = $(document.getElementById(url));
                $element.find('.leancloud-visitors-count').text(newcounter.get('time'));
              },
              error: function(newcounter, error) {
                console.log('Failed to create');
              }
            });
          }
        },
        error: function(error) {
          console.log('Error:' + error.code + " " + error.message);
        }
      });
    }

    $(function() {
      var Counter = AV.Object.extend("Counter");
      if ($('.leancloud_visitors').length == 1) {
        addCount(Counter);
      } else if ($('.post-title-link').length > 1) {
        showTime(Counter);
      }
    });
  </script>



  

  
<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>


  
  
  
  <link rel="stylesheet" href="/lib/needsharebutton/needsharebutton.css">

  
  
  <script src="/lib/needsharebutton/needsharebutton.js"></script>

  <script>
    
      pbOptions = {};
      
          pbOptions.iconStyle = "default";
      
          pbOptions.boxForm = "vertical";
      
          pbOptions.position = "top";
      
          pbOptions.networks = "Weibo,Wechat,Douban,QQZone,Twitter,Facebook";
      
      new needShareButton('#needsharebutton-postbottom', pbOptions);
    
    
      flOptions = {};
      
          flOptions.iconStyle = "box";
      
          flOptions.boxForm = "horizontal";
      
          flOptions.position = "middleRight";
      
          flOptions.networks = "Weibo,Wechat,Douban,QQZone,Twitter,Facebook";
      
      new needShareButton('#needsharebutton-float', flOptions);
    
  </script>

  

  
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


  
  <script type="text/javascript" src="/js/src/js.cookie.js?v=5.1.4"></script>
  <script type="text/javascript" src="/js/src/scroll-cookie.js?v=5.1.4"></script>


  
  <script type="text/javascript" src="/js/src/exturl.js?v=5.1.4"></script>


  
  
  	 <!-- custom analytics part create by xiamo -->
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
<script>AV.initialize("2AyV3DKioBSdoryrFLRohzjB-gzGzoHsz", "XynedcHyJCVCrTfbD4yYnodo");</script>
<script>
function showTime(Counter) {
	var query = new AV.Query(Counter);
	$(".leancloud_visitors").each(function() {
		var url = $(this).attr("id").trim();
		query.equalTo("url", url);
		query.find({
			success: function(results) {
				if (results.length == 0) {
					var content = $(document.getElementById(url)).text() + ' 0';
					$(document.getElementById(url)).text(content);
					return;
				}
				for (var i = 0; i < results.length; i++) {
					var object = results[i];
					var content = $(document.getElementById(url)).text() + ' ' + object.get('time');
					$(document.getElementById(url)).text(content);
				}
			}
		});

	});
}

</script>
  
</body>
</html>
